//
//  PhotosManager.swift
//  GreenDeal
//
//  Created by Moennig Q on 21/12/2022.
//  抽取从图库选取图片的

import UIKit
import Photos
import PhotosUI
class PhotosManager: PHPickerViewControllerDelegate {
    private var currentVC: UIViewController!
    private var maxCount: Int = 1
    private var assertFlag: Bool = false
    var closure: ((PHAsset?,String?)->Void)?
    
    static let shared: PhotosManager = PhotosManager()
    
    func initData(vc: UIViewController, maxCount: Int,closure: @escaping ((Any?,String?)->Void))->PhotosManager{
        self.currentVC = vc
        self.maxCount = maxCount
        self.closure = closure
        return self
    }
    //MARK: - assertFlag = true表示获取原始Assert数据，false表示获取imageData数据
    func getPhotos(assertFLag: Bool = false){
        self.assertFlag = assertFLag
        if #available(iOS 14, *) {//iOS 14之后的相册选择（包括14）
            let level = PHAccessLevel.readWrite
            PHPhotoLibrary.requestAuthorization(for: level){ (status) in
                DispatchQueue.main.async {
                    if status == .authorized {//全部相片
                        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
                        configuration.filter = .images
                        configuration.selectionLimit = self.maxCount//最多选择10个
                        let picker = PHPickerViewController(configuration: configuration)
                        picker.delegate = self
                        picker.modalPresentationStyle = .overFullScreen
                        self.currentVC.present(picker, animated: true)
                    }else if status == .limited{//部分相片
                        self.selectFromPhotosLibraryBefore()
                    }else {//无权限
                        self.closure?(nil,R.string.localizable.photosPermission())
                        return
                    }
                }
            }
        }else{//14以前的
            PHPhotoLibrary.requestAuthorization({ (status) in
                DispatchQueue.main.async {
                    if status == .authorized {//有权限
                        self.selectFromPhotosLibraryBefore()
                    }else{//无权限
                        self.closure?(nil,NSLocalizedString("photos.permission", comment: ""))
                        return
                    }
                }
            })
        }
    }
    //自定义相册
    fileprivate func selectFromPhotosLibraryBefore(){
        _ = currentVC.presentHGImagePicker(maxSelected: maxCount) { (assets) in
            for asset in assets{
                self.closure?(asset, nil)
            }
        }
    }
    //MARK: - iOS 14以后，从相册选择图片回调,PHPickerViewControllerDelegate
    @available(iOS 14, *)
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true) {//代码必需加到回调中，防止选图片界面dismiss反应慢，导致Add可以点击多次导致增加n多图片
            guard results.count > 0 else {
                return
            }
            for result in results {
                if let assertId = result.assetIdentifier,
                   let assert = PHAsset.fetchAssets(withLocalIdentifiers: [assertId], options: nil).firstObject
                {
                    self.closure?(assert,nil)
                }
            }
        }
    }
    //MARK: - (pvd)增加checklist的image数据
    func addImageFromPhotosForPVDJob(_ assert: Any,lodgedCheck: Bool){
        guard let assert = assert as? PHAsset else{ return }
        let photoModel = self.getPhotoModelFromAssert(assert)
        var resultData: NSData?
        if lodgedCheck  {//true上传原图
            MediaUtil().getOrignalImageDataOfPHAsset(asset: assert) { nsdata in
//                let sourceNew = CGImageSourceCreateWithData(nsdata as CFData, nil)!
//                let metadataNew = CGImageSourceCopyPropertiesAtIndex(sourceNew, 0, nil) as? [AnyHashable: Any]
                let data = (nsdata as Data)
                if  data.getImageFormat() == .HEIC{
                    guard let originImage = MediaUtil().getUIImage(asset: assert) else{return}
                    resultData = MediaUtil().resetSizeOfImageData(source_image: originImage)
                    self.savePVDImageData(resultData, photoModel: photoModel,photoSource: .selectFromPhotoLibrary)
                }else{
                    self.savePVDImageData(nsdata, photoModel: photoModel,photoSource: .selectFromPhotoLibrary)
                }
                
            }
        }else{//false压缩图片，
            guard let originImage = MediaUtil().getUIImage(asset: assert) else{return}
            resultData = MediaUtil().resetSizeOfImageData(source_image: originImage)
            self.savePVDImageData(resultData, photoModel: photoModel,photoSource: .selectFromPhotoLibrary)
        }
        
    }
    //MARK: - (service job)增加checklist的image数据
    func addImageFromPhotosForServiceJob(_ assert: Any){
        guard let assert = assert as? PHAsset else{ return }
        if let data = self.getImageDataFromAssert(assert){
            self.saveServiceImageData(data, fileType: .image)
        }
    }
    func getImageDataFromAssert(_ assert: PHAsset)->Data?{
        guard let originImage = MediaUtil().getUIImage(asset: assert) else{return nil}
        let resultData: NSData = MediaUtil().resetSizeOfImageData(source_image: originImage)
        return resultData as Data
    }
    //MARK: - 从相册图片中获取GPS信息和创建日期
    private func getPhotoModelFromAssert(_ assert: PHAsset)->ChecklistPhotoModel{
        var photoModel = ChecklistPhotoModel()
        if let data = assert.creationDate{
            photoModel.createdAt = DateUtil().getDatetimeStr(data)
        }
        if let data = assert.location?.coordinate.longitude{
            photoModel.longitude = "\(data)"
        }
        if let data = assert.location?.coordinate.latitude{
            photoModel.latitude = "\(data)"
        }
        return photoModel
    }
    //MARK: - take photo和selectImageFromlibray共用此代码
    func savePVDImageData(_ resultData: NSData?, photoModel: ChecklistPhotoModel,fileType: ChecklistFileType = .image,photoSource: PhotoSource){
        guard let originImageData = resultData else{return}
        let fileName = DateUtil().getCurrentDatetimeTamp()
        //checklist image
        
        var imagePath = ""
        if fileType == .image {
            imagePath = FileUtil().getChecklistImagePath(fileName,fileSuffix: APPConfig.ImageSuffix)
            
        }else{
            imagePath = FileUtil().getChecklistImagePath(fileName,fileSuffix: APPConfig.PDFSuffix)
        }
        do {
            try originImageData.write(to: URL(fileURLWithPath: imagePath), options: [.atomic])
            
            let imageModel = CheckListImageDBModel()
            imageModel.pvd_id = JobDetailModelHelper.shared.jobDetailModel.id
            imageModel.checklist_id = JobDetailModelHelper.shared.checklistModel.id
            imageModel.record_at = DateUtil().getCurrentDatetime()
            imageModel.photo_source = photoSource.rawValue//图片来源于相册或相机拍照
            imageModel.photo_created_at = photoModel.createdAt
            imageModel.latitude = photoModel.latitude
            imageModel.longitude = photoModel.longitude
            imageModel.image = imagePath
            imageModel.id = fileName
            imageModel.title = JobDetailModelHelper.shared.checklistModel.title
            imageModel.oper_type = DataOperType.Add.rawValue
            
            //0.必须先插入数据库，因为broadCast时，有地方（flush upload）会用到本地数据的统计
            DBManager.shared.insertChecklistImages(model: imageModel)
            //1.增加到当前list中
            JobDetailModelHelper.shared.checklistModel.images.insert(imageModel, at: 0)
            if let index = JobDetailModelHelper.shared.jobDetailModel.pvd_checklists.firstIndex(where: {$0.id == JobDetailModelHelper.shared.checklistModel.id}){
                JobDetailModelHelper.shared.jobDetailModel.pvd_checklists[index] = JobDetailModelHelper.shared.checklistModel
                JobDetailModelHelper.shared.jobDetailModel.broadCastChecklistData()
            }
            //2.上传
            //noc,other attachment是假的checklist，需要调用上传附件API
            if imageModel.checklist_id == ChecklistFixedId.nocAttachment.rawValue || imageModel.checklist_id == ChecklistFixedId.otherAttachment.rawValue{
                UploadManager.shared.uploadAttachment(imageModel: imageModel)
            }else{
                UploadManager.shared.uploadChecklistImage(imageModel: imageModel)
            }
            
        }catch{
            NSLog("Saving checklist image to local failed")
        }
    }
    //MARK: - service job : take photo和selectImageFromlibray共用此代码
    func saveServiceImageData(_ resultData: Data?, fileType: ChecklistFileType = .image){
        guard let originImageData = resultData else{return}
        let fileName = DateUtil().getCurrentDatetimeTamp()
        //checklist image
        
        var imagePath = ""
        if fileType == .image {
            imagePath = FileUtil().getServiceChecklistImagePath(fileName,fileSuffix: APPConfig.ImageSuffix)
            
        }else{
            imagePath = FileUtil().getServiceChecklistImagePath(fileName,fileSuffix: APPConfig.PDFSuffix)
        }
        do {
            try originImageData.write(to: URL(fileURLWithPath: imagePath), options: [.atomic])
            
            let imageModel = CheckListImageDBModel()
            imageModel.pvd_id = ServiceDetailModelHelper.shared.serviceDetailModel.serviceID
            imageModel.checklist_id = ServiceDetailModelHelper.shared.checklistModel.id
            imageModel.record_at = DateUtil().getCurrentDatetime()
            imageModel.image = imagePath
            imageModel.id = fileName
            imageModel.title = ServiceDetailModelHelper.shared.checklistModel.title
            imageModel.oper_type = DataOperType.Add.rawValue
            
            //0.必须先插入数据库，因为broadCast时，有地方（flush upload）会用到本地数据的统计
            DBManager.shared.insertServiceChecklistImages(model: imageModel)
            //1.增加到当前list中
            ServiceDetailModelHelper.shared.checklistModel.images.insert(imageModel, at: 0)
            if let index = ServiceDetailModelHelper.shared.serviceDetailModel.checklists.firstIndex(where: {$0.id == ServiceDetailModelHelper.shared.checklistModel.id}){
                ServiceDetailModelHelper.shared.serviceDetailModel.checklists[index] = ServiceDetailModelHelper.shared.checklistModel
                ServiceDetailModelHelper.shared.serviceDetailModel.broadCastChecklistData()
            }
            //2.上传
            //需要调用上传附件API
            UploadManager.shared.uploadServiceChecklistImage(imageModel: imageModel)
            
        }catch{
            NSLog("Saving checklist image to local failed")
        }
    }
    //MARK: - 设置拍照是的GPS信息后，保存相片
    func dealPhotoFromTakePhoto(originImage: UIImage, photoSource: PhotoSource){
        let originImageData = MediaUtil().resetSizeOfImageData(source_image: originImage)
        guard let dataWithMetadata = self.setExifInfoToImage(originImageData) else {return}
        var photoModel = ChecklistPhotoModel()
        photoModel.createdAt = DateUtil().getDatetimeStr()
        photoModel.latitude =  APPConfig.currentLocation.latitude
        photoModel.longitude = APPConfig.currentLocation.longitude
        self.savePVDImageData(dataWithMetadata, photoModel: photoModel,photoSource: photoSource)
    }
    //MARK: - 设置拍照是的GPS信息
    fileprivate func setExifInfoToImage(_ imageData: NSData)->NSData?{
        if let source = CGImageSourceCreateWithData(imageData as CFData, nil),let metadata = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [AnyHashable: Any]{
            var multipleMetadata = metadata
            var exifDictionary = multipleMetadata[kCGImagePropertyExifDictionary as String] as? [AnyHashable: Any]
            var gpsDictionary = multipleMetadata[kCGImagePropertyGPSDictionary as String] as? [AnyHashable: Any]
            
            if exifDictionary == nil{
                exifDictionary = [AnyHashable: Any]()
            }
            if gpsDictionary == nil{
                gpsDictionary = [AnyHashable: Any]()
            }
            gpsDictionary![(kCGImagePropertyGPSLatitude as String)] = APPConfig.currentLocation.latitude
            gpsDictionary![(kCGImagePropertyGPSLongitude as String)] = APPConfig.currentLocation.longitude
            exifDictionary![(kCGImagePropertyExifDateTimeOriginal as String)] = DateUtil().getDatetimeStr(format: "yyyy:MM:dd HH:mm:ss")
            exifDictionary![(kCGImagePropertyExifDateTimeDigitized as String)] = DateUtil().getDatetimeStr(format: "yyyy:MM:dd HH:mm:ss")

            if #available(iOS 13.0, *) {
                exifDictionary![(kCGImagePropertyExifOffsetTime as String)] = TimeZone.current.abbreviation()//"+08:00"
                exifDictionary![(kCGImagePropertyExifOffsetTimeOriginal as String)] = TimeZone.current.abbreviation()//"+08:00"
                exifDictionary![(kCGImagePropertyExifOffsetTimeDigitized as String)] = TimeZone.current.abbreviation()//"+08:00"
            }
            
             multipleMetadata[kCGImagePropertyGPSDictionary as String] = gpsDictionary!
             multipleMetadata[kCGImagePropertyExifDictionary as String] = exifDictionary!
            
            if let UTI = CGImageSourceGetType(source){
                let dest_data = NSMutableData(data: imageData as Data)
                let destination: CGImageDestination = CGImageDestinationCreateWithData(dest_data, UTI, 1, nil)!
                CGImageDestinationAddImageFromSource(destination, source, 0, (multipleMetadata as CFDictionary?))
                CGImageDestinationFinalize(destination)
//                let sourceNew = CGImageSourceCreateWithData(dest_data as CFData, nil)!
//                let metadataNew = CGImageSourceCopyPropertiesAtIndex(sourceNew, 0, nil) as? [AnyHashable: Any]
//                print(metadataNew)
                return dest_data as NSData
            }
            return nil
        }
        return nil
    }
}
